/*
 * mn.c
 *
 *  Created on: 2011-6-15
 *      Author: vyouzhi
 *
 *int main()
 *{
 *	Sdb *sdb ;
 *	sdb = GetData();
 *	PrintData(sdb);
 *	DestroyData(sdb);
 * 	printf("ok ---\n");	
 *	
 *	
 *	return 0;
 *}
 */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "sdb_struct.h"

/* column */

SdbColumn *SdbColumn_init(void) {
	SdbColumn *column = (struct SdbColumn *)calloc(1, sizeof(struct SdbColumn));
	if (column == NULL) printf("can't calloc for SdbColumn_init");
	return column;
}

void SdbColumn_destroy(SdbColumn *column) {
	free(column->field);
	free(column->value);
	free(column);
}

/* row */

SdbRow *SdbRow_init(void) {
	SdbRow *row = (struct SdbRow *)calloc(1, sizeof(struct SdbRow));
	if (row == NULL) printf("can't calloc for SdbRow_init");
	return (row);
}

void SdbRow_addColumn(SdbRow *row, char *field, char *value) {
	SdbColumn **saveTo = &row->firstColumn;
	SdbColumn *newColumn;

	if (*saveTo) {
		while ((*saveTo)->next) {
			saveTo = &(*saveTo)->next;
		}
	}

	newColumn = SdbColumn_init();
	newColumn->field = strdup(field);
	newColumn->value = value ?  strdup(value) : value;

	newColumn->next = *saveTo;
	*saveTo = newColumn;
}

void SdbRow_removeColumn(SdbRow *row, int pos) {
#ifdef FIXME
	SdbColumn *sd = row->firstColumn;
	int cur_pos=0;

	if (pos<1 || pos>SdbColumn_length(column)) exit(1);

	while (sd && cur_pos<pos-1) {
		sd = sd->next;
		cur_pos++;
	}

	sd->next = sd->next->next;
#endif
}

int SdbRow_empty(SdbRow *row) {
	if (row->firstColumn == NULL) return(1);
	else return(0);
}

int SdbRow_length(SdbRow *row) {
	SdbColumn *column;
	int length = 0;

	for (column = row->firstColumn; column; column = column->next) {
		++length;
	}
	return length;
}

SdbColumn SdbRow_GetNode(SdbRow *row, int pos) {
	SdbColumn *column = row->firstColumn;
	int cur_pos = 0;

	if (pos < 1 || pos > SdbRow_length(row)) exit(1);

	while (column && cur_pos < pos) {
		column=column->next;
		cur_pos++;
	}

	return *column;
}

void SdbRow_destroy(SdbRow *row) {
	SdbColumn *column, *nextColumn;

	for (column = row->firstColumn; column; column = nextColumn) {
		nextColumn = column->next;
		SdbColumn_destroy(column);
	}
	free(row);
}

/* sdb */

Sdb *Sdb_init(void) {
	Sdb *sdb = (struct Sdb *)calloc(1, sizeof(struct Sdb));
	if (sdb == NULL) printf("can't calloc for Sdb_init");
	return (sdb);
}

int Sdb_empty(Sdb *sdb) {
	if (sdb->firstRow == NULL) return(1);
	else return(0);
}

int Sdb_length(Sdb *sdb) {
	SdbRow *row;
	int length = 0;

	for (row = sdb->firstRow; row; row = row->next) {
		++length;
	}

	return length;
}

void Sdb_appendRow(Sdb *sdb, SdbRow *newRow) {
	SdbRow **saveTo = &sdb->firstRow;

	if (*saveTo) {
		while (*saveTo) {
			saveTo = &(*saveTo)->next;
		}
	}
	newRow->next = *saveTo;
	*saveTo = newRow;
}

void Sdb_destroy(Sdb *sdb) {
	SdbRow *row, *nextRow;

	/*for (row = sdb->firstRow; row; row = nextRow) {*/
	if(sdb != NULL){
		row = sdb->firstRow;
		while(row != NULL ){
			nextRow = row->next;
			SdbRow_destroy(row);
			row = nextRow;
		}
		free(sdb);
	}
}

Sdb *GetData(void) {
	int columnNumber, n;
	Sdb *sdb = Sdb_init();
	SdbRow *row;

	for (n=0;n<4;n++) {
		row = SdbRow_init();

		for (columnNumber = 0; columnNumber < 8; columnNumber++) {
			SdbRow_addColumn(row, "f","v");
		}

		Sdb_appendRow(sdb, row);
	}
	return sdb;
}

void PrintData(Sdb *sdb) {
	int columnNumber = 0;
	SdbRow *readrow;
	SdbColumn *readcolumn;	
	/*	printf("SdbColumn size is %lu\n", sizeof(SdbColumn));
		printf("SdbRow size is %lu\n", sizeof(SdbRow));
	*/
	for(readrow = sdb->firstRow; readrow; readrow=readrow->next){
		for(readcolumn=readrow->firstColumn; readcolumn; readcolumn=readcolumn->next){
			/*printf("%d: psd is  field: %s, value: %s\n", columnNumber, readcolumn->field, readcolumn->value);*/
			columnNumber++;
		}

	}

}

void DestroyData(Sdb *sdb){
	Sdb_destroy(sdb);
}

